package com.woniuxy.lab.woniu_lab.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniuxy.lab.woniu_lab.commons.Result;

import com.woniuxy.lab.woniu_lab.controller.form.CheckCodeForm;
import com.woniuxy.lab.woniu_lab.controller.form.GetCodeForm;
import com.woniuxy.lab.woniu_lab.controller.form.RegisterForm;
import com.woniuxy.lab.woniu_lab.exception.WebException;
import com.woniuxy.lab.woniu_lab.model.User;
import com.woniuxy.lab.woniu_lab.service.UserService;
import com.woniuxy.lab.woniu_lab.service.dto.UserDto;
import com.woniuxy.lab.woniu_lab.util.JwtUtil;
import com.woniuxy.lab.woniu_lab.util.MD5Util;
import com.woniuxy.lab.woniu_lab.util.WebUtil;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.constraints.Length;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import java.math.BigDecimal;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author Silas
 * @since 2023-03-15
 */
@RestController
@RequestMapping("/user")
@Api(tags = "[L]用户相关接口")
@Slf4j
@Validated
public class UserController {
    @Resource
    private UserService userService;



    @ApiOperation("09 密码登陆")
    @GetMapping("login")
    public Result<Object> login(@ApiParam(value = "手机号") @NotBlank(message = "手机号不能为空")
                                    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确") String phone,
                                @ApiParam(value = "密码") @NotBlank(message = "密码不能为空") String password) {
        log.info("{}执行密码登陆操作", phone);
        String token = userService.loginByPwd(phone, password);
        return Result.success(200, "登录成功", token);
    }

    @ApiOperation("10 短信验证码登陆")
    @GetMapping("loginByText")
    public Result<String> loginByText(@ApiParam(value = "手机号")  @NotBlank(message = "手机号不能为空")
                                     @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确") String phone,
                                      @ApiParam(value = "验证码") @NotBlank(message = "验证码不能为空") String code) {
        log.info("{}执行短信验证码登陆操作，验证码为{}", phone, code);
        String token = userService.loginByCode(phone, code);
        return Result.success(200, "登录成功", token);
    }

    @ApiOperation("24 获取我的账户余额")
    @GetMapping("queryBalance")
    public Result<BigDecimal> queryBalance() {
        log.info("查询当前用户余额");
        User user = userService.assertUser();
        return Result.success(200, "查询成功", user.getBalance());
    }


    @ApiOperation("29 获取用户会员状态")
    @GetMapping("queryUserVipState")
    public Result<String> queryUserVipState() {
        log.info("获取用户会员状态");
        User user = userService.assertUser();
        return Result.success(200, "查询成功", user.getVip());
    }

    @ApiOperation("30 成为年费会员")
    @PutMapping("becomeVIP")
    public Result<Object> becomeVIP(@ApiParam(value = "支付密码") @RequestParam @NotBlank(message = "密码不能为空") String password) throws Exception {
        log.info("成为年费会员,密码{}", password);
        String MD5Password = MD5Util.MD5(password);
        String message= userService.becomeVIP(MD5Password);
        return Result.success(200, "感谢您的支持,"+message+",会员期间本站所有内容免费对您开放", null);
    }


    @ApiOperation("31 成为终身会员")
    @PutMapping("becomeSVIP")
    public Result<Object> becomeSVIP(@ApiParam(value = "支付密码") @RequestParam @NotBlank(message = "密码不能为空") String password) throws Exception {
        log.info("成为终身会员{}", password);
        String MD5Password = MD5Util.MD5(password);
        userService.becomeSVIP(MD5Password);
        return Result.success(200, "感谢您的支持,您已升级为本站的终身会员,本站所有内容免费对您开放", null);
    }


    @ApiOperation("04 获取用户头像")
    @GetMapping("/findUserPic")
    public Result<String> findUserPic() {
        User user = userService.assertUser();
        log.info("获取用户{}头像", user.getId());
        String pic = user.getPic();
        return Result.success(200, "获取用户头像成功", pic);
    }

    @ApiOperation("05 验证手机号是否存在")
    @GetMapping("/checkPhone")
    public Result<Boolean> checkPhone(@ApiParam(value = "手机号") @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确") String phone) {
        log.info("验证手机号{}是否存在", phone);
        User user = userService.getOne(new QueryWrapper<User>().eq("phone", phone));
        if (user == null) return Result.success(200, "该手机号不存在", false);
        return Result.success(200, "该手机号存在", true);
    }

    @ApiOperation("07 判断验证码是否正确")
    @PostMapping("/checkCode")
    @ApiResponse(code = 200, message = "返回true表示验证码正确", response = Boolean.class)
    public Result<Boolean> checkCode(@RequestBody CheckCodeForm form) {
        log.info("校验验证码 {}", form);
        Boolean flag = userService.checkCode(form);
        return Result.success(200, "SUCCESS", flag);
    }

    @ApiOperation("08 用户注册")
    @PostMapping("/register")
    public Result<Object> register(@RequestBody @Valid RegisterForm registerForm) {
        log.info("执行注册操作：{}", registerForm);
        userService.register(registerForm);
        return Result.success(200, "注册成功", null);
    }

    @ApiOperation("11 重置密码")
    @PutMapping("resetPassword")
    public Result<Object> resetPassword(@ApiParam(value = "手机号") @RequestParam @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
                                            @NotBlank(message = "手机号不能为空") String phone,
                                        @ApiParam(value = "密码") @RequestParam @NotBlank(message = "密码不能为空") String password) {
        log.info("用户{}执行找回密码操作", phone);
        userService.findMyPwd(phone, password);
        return Result.success(200, "重置密码成功", null);
    }

    @ApiOperation("12 获取我的个人信息")
    @GetMapping("/fingMyInfo")
    public Result<UserDto> findMyInfo() {
        Integer userId = JwtUtil.getUserIdFromReq();
        log.info("查询{}个人信息", userId);
        User user = userService.getById(userId);
        UserDto userDto = BeanUtil.copyProperties(user, UserDto.class);
        return Result.success(200, "查看我的个人信息成功", userDto);
    }

    @ApiOperation("13 修改昵称")
    @PutMapping("/modifyMyInfo")
    public Result<Object> modifyMyInfo(@ApiParam(value = "新昵称") @RequestParam @NotBlank(message = "昵称不能为空")
                                           @Length(max = 15,min = 2,message = "昵称长度为2到15位") String nickname) {
        Integer userId = JwtUtil.getUserIdFromReq();
        log.info("修改用户{}的昵称{}", userId, nickname);
        User user = userService.getById(userId);
        user.setNickname(nickname);
        userService.updateById(user);
        return Result.success(200, "修改昵称成功", null);
    }

    @ApiOperation("15 修改头像")
    @PutMapping("modifyMyPic")
    public Result<String> modifyMyPic(@ApiParam(value = "新头像文件") @RequestPart(value = "file")
                                          @NotNull(message = "头像不能为空") MultipartFile file) {
        log.info("用户修改头像{}", file);
        String picUrl = userService.updatePic(file);
        return Result.success(200, "修改头像成功", picUrl);
    }

    @ApiOperation("14 修改密码")
    @PutMapping("modifyPassword")
    public Result<Boolean> changePassword(@ApiParam(value = "原密码") @RequestParam @NotBlank(message = "原密码不能为空") String password,
                                          @ApiParam(value = "新密码") @RequestParam @NotBlank(message = "新密码不能为空")
                                          @Pattern(regexp = "^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z0-9]{8,20}$",message = "新密码长度应为8-20位，必须包含英文大小写+数字") String newPassword) {
        Integer userId = JwtUtil.getUserIdFromReq();
        log.info("用户{}执行修改密码操作{}{}",userId, password, newPassword);
        userService.changePwd(userId, password, newPassword);
        return Result.success(200, "SUCCESS", null);
    }

    @ApiOperation("06 获取验证码")
    @PostMapping("getCode")
    public Result<Object> getCode(@RequestBody @Valid GetCodeForm form){
        log.info("获取验证码 {}", form);
        String code = userService.sendCode(form);
        return Result.success(200, "SUCCESS", null);
    }

}

